<?php

namespace catchAdmin\stock\controller;

use catchAdmin\product\model\Product;
use catchAdmin\stock\model\StatStock;
use catchAdmin\stock\model\WarehouseConfig;
use catchAdmin\storehouse\model\Project;
use catchAdmin\storehouse\model\WarehouseOut;
use catchAdmin\storehouse\model\Warehousing;
use catcher\base\CatchRequest as Request;
use catcher\CatchResponse;
use catcher\base\CatchController;
use catchAdmin\stock\model\Stock as StockModel;
use think\facade\Log;
use think\Response;
use think\facade\Db;
use catcher\CatchAuth;
use catcher\library\excel\Excel;
use catchAdmin\stock\excl\stockExport;

class Stock extends CatchController
{
    
    protected $stockModel;
    
    /**
     *
     * @time 2022/01/23 13:52
     * @param StockModel $stockModel
     * @return mixed
     */
    public function __construct(StockModel $stockModel)
    {
        $this->stockModel = $stockModel;
    }
    
    /**
     *
     * @time 2022/01/23 13:52
     * @return Response
     */
    public function index(CatchAuth $auth,Request $request) : Response
    {
        $config_name = $request->post('config_name');
        $goods_status = $request->post('goods_status');
        $customer_business_number = $request->post('customer_business_number');
        $user = $auth->user();
        return CatchResponse::paginate($this->stockModel->getList($user['tenant_id'],$config_name,$goods_status,$customer_business_number));
    }
    
    /**
     * 一键入库
     * @time 2022/01/23 13:52
     * @param Request $request
     * @return Response
     */
    public function create(CatchAuth $auth,Request $request) : Response
    {
         $user = $auth->user();
         $data = $request->filterEmptyField()->post();
         $params = $this->info($user['tenant_id'],$data);
         if($params['code'] === 0){
            return CatchResponse::fail($params['msg']);
         }
//        $sql=Db::table('db_stock')->fetchSql(true)->insertAll($params['data']);
//        return CatchResponse::fail($sql);
         Db::startTrans();
        try {
            Db::table('db_stock')->insertAll($params['data']);
            //$this->stockModel->insertAllBy($params['data']);
            $this->status($data);
            Db::commit();
            return CatchResponse::success([],'入库成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail('入库失败');
        }
    }
    
    /**
     * 取消入库
     * @time 2022/01/23 13:52

     * @param Request $request
     * @return Response
     */
    public function delete(Request $request) : Response
    {
        $params = $request->post();
        $where = [];
        $where[] = ['tray_id','in',$params['tray_id']];
        $where[] = ['split_status','=','0'];
        $where[] = ['status','=','0'];
        $where[] = ['out_number','=','0'];
        $stock = Db::name('db_stock')->where($where)->delete();
        unset($params['tray_id']);
        $params['cancel'] = 1;
        if($stock > 0){
            Db::startTrans();
            try {
                 $this->status($params);
                Db::commit();
                return CatchResponse::success('取消入库成功');
            } catch (\Exception $exception) {
                Db::rollback();
                return CatchResponse::fail('取消入库失败');
            }
        }else{
            return CatchResponse::fail('请选择已入库未拆分未出库的数据');
        }
    }
    /**
     * 入库信息
     * @time 2022/01/23 13:53
     * @param Request $request
     * @return array
     */
    public function info($tenant_id,$params){
        $where = [];
        $where[] = ['t.id','in',$params['id']];
        $where[] = ['t.status','=','0'];

        $tray = DB::name('db_tray')->alias('t')
                        ->join('db_warehousing_son s','s.warehousing_son_id = t.warehousing_son_id')
                        ->join('db_warehousing w','w.warehousing_id = t.warehousing_id')
                        ->field('s.warehousing_id,s.warehousing_son_id,s.goods_id,s.HSCODE,s.goods_name,s.goods_Cname,s.goods_Ename,s.supplier_id,s.supplier_name,s.manufacturer_id,s.manufacturer_name,s.packing_id,s.p_barcode,s.packing_num,s.unit_name,s.batch_number,w.project_id,w.project_client,t.tray_id,t.config_id,t.number,t.box_number,t.goods_status')
                        ->where($where)
                        ->select()
                        ->toArray();

        foreach ($tray as $key => $value) {
            $tray[$key]['stock_id'] = date('YmdHis').mt_rand(1000,9999);
            $tray[$key]['tenant_id'] = $tenant_id;
            //加入仓库字段
            $config_id=$value['config_id'];
            $p_id=Db::table('db_warehouse_config')->where('config_id',$config_id)->value('parent_id');
            $p_info=Db::table('db_warehouse_config')->where('id',$p_id)->find();
            if($p_info['parent_id'] != 0){
                $p_info=Db::table('db_warehouse_config')->where('id',$p_info['parent_id'])->find();
            }
            $tray[$key]['entrepot_id']=$p_info['config_id'];
            $tray[$key]['entrepot_name']=$p_info['name'];

            if($value['goods_status'] == 'Good'){
                $tray[$key]['Good_Qty'] = $value['number'];

            }elseif($value['goods_status'] == 'NG'){
                $tray[$key]['NG_Qty'] = $value['number'];

            }elseif($value['goods_status'] == 'Hold'){
                $tray[$key]['Hold_Qty'] = $value['number'];
            }
            unset($tray[$key]['goods_status']);
        }
        if(empty($tray)){
            return array('code'=>0,'msg'=>'请选择未入库的数据');
        }
        return array('code'=>1,'data'=>$tray);
    }
    /**
     * 入库状态改变
     * @time 2022/01/23 13:53
     * @param Request $request
     * @return string
     */
    public function status($data){
        //托盘状态
        if(array_key_exists('cancel',$data) === true){
            $res['status'] = '0';
            unset($data['cancel']);
        }else{
            $res['status'] = '1';
        }
        $res['updated_at'] = time();

        DB::name('db_tray')->where('id','in',$data['id'])->update($res);

        //入库明细单状态

        //统计托盘数量
        $where['warehousing_son_id'] = $data['warehousing_son_id'];
        $where['status'] = '1';
        $tray = DB::name('db_tray')->where($where)->sum('number');

        //改变入库子单状态
        $warehousing_son = DB::name('db_warehousing_son')->where('warehousing_son_id',$data['warehousing_son_id'])->value('number');

        if((intval($tray) != 0) && (intval($tray) < intval($warehousing_son))){
            $res1['status'] = '2';
        }elseif(intval($tray) == intval($warehousing_son)){
            $res1['status'] = '1';
        }else{
            $res1['status'] = '0';
        }
        $res1['actual_number'] = $tray;
        $res1['updated_at'] = time();

        DB::name('db_warehousing_son')->where('warehousing_son_id',$data['warehousing_son_id'])->update($res1);


        //入库主单状态

        //入库子单实际入库数量和状态
        $where1['warehousing_id'] = $data['warehousing_id'];
        $where1['status'] = '1';
        $son_number =  DB::name('db_warehousing_son')->where($where1)->sum('actual_number');

        //改变入库主单状态
        $warehousing = DB::name('db_warehousing')->where('warehousing_id',$data['warehousing_id'])->value('goods_number');

        if((intval($son_number) != 0) && (intval($son_number) < intval($warehousing))){
            $res2['status'] = '2';
        }elseif(intval($son_number) == intval($warehousing)){
            $res2['status'] = '1';
        }else{
            $res2['status'] = '0';
        }

        $res2['actual_number'] = $son_number;
        $res2['updated_at'] = time();
        DB::name('db_warehousing')->where('warehousing_id',$data['warehousing_id'])->update($res2);
    }
    /**
     * 库位信息
     * @time 2022/01/23 13:52

     * @param Request $request
     * @return Response
     */
    public function seatList(Request $request)
    {
        $params = $request->post();
        $p_name=Db::table('db_warehouse_config')->where('id',$params['parent_id'])->value('name');
        $title=$p_name.'   >   '.$params['name'];
        $where=[];
        $where[]=['a.parent_id','=',$params['id']];
        //$where[]=['b.status','<>',1];
        $data=Db::table('db_warehouse_config')
            ->alias('a')
            ->field("a.id,a.config_id,a.name,a.serial_number,a.usage,a.isstatus,a.max_load_weight,a.max_load_length,a.max_load_width,a.max_load_height")
            //->leftJoin('db_stock b','a.config_id=b.config_id')
            ->where($where)
            ->order('a.sort desc')
            ->select()
            ->toArray();
//        return $params['id'];
        

        //优化1-过程
        $_stock_arr_config_ids = array_column($data,'config_id');

        $_stock_arr = $this->stockModel->field('config_id,sum(Good_Qty + Hold_Qty + NG_Qty) as stock,COUNT(DISTINCT tray_id) AS layup_num')->where([
            ['config_id','in',$_stock_arr_config_ids],
            ['status','<>',1]
        ])->group('config_id')->select()->toArray();

        $_stock_arr2 = array_column($_stock_arr,null,'config_id');

        foreach ($data as $k=>$v){
            $map=[];
            $map[]=['status','<>',1];
            $map[]=['config_id','=',$v['config_id']];

            //一库位多个托盘
//            $arr=Db::table('db_stock')->field('sum(number) as s_num,sum(out_number) as s_out')->where($map)->select()->toArray();
           // $arr=Db::table('db_stock')->field('sum(Good_Qty + Hold_Qty + NG_Qty) as stock')->where($map)->find();

           // $arr1_tray = Db::table('db_stock')->where($map)->column('tray_id');

//            $temp_s_num = array_sum(array_column($arr,'s_num'));
//            $temp_s_out = array_sum(array_column($arr,'s_out'));
//            $data[$k]['stock'] = $temp_s_num-$temp_s_out;

            if(array_key_exists($v['config_id'],$_stock_arr2)){
                $data[$k]['stock'] =   (int)$_stock_arr2[$v['config_id']]['stock'];
                $data[$k]['layup_num'] =  (int)$_stock_arr2[$v['config_id']]['layup_num'];
            }else{
                $data[$k]['stock'] = $data[$k]['layup_num'] =  0;
            }

            //$data[$k]['layup_num'] = count(array_unique($arr1_tray));
//            //一库位一托盘
//            $arr=Db::table('db_stock')->field('sum(number) as s_num,sum(out_number) as s_out')->where($map)->find();
//            $data[$k]['stock']=$arr['s_num']-$arr['s_out'];
        }

        //$arr =  array_count_values($data['usage']);
        $usage_arr = array_count_values(array_column($data,'usage'));

        $total_config_counts = count($data);//总库位
        $usage_1_counts = array_key_exists('1',$usage_arr)  ? $usage_arr[1] : 0;
        $usage_2_counts = array_key_exists('2',$usage_arr)  ? $usage_arr[2] : 0;
        $usage_3_counts = array_key_exists('3',$usage_arr)  ? $usage_arr[3] : 0;
        $total_counts = array_sum(array_column($data,'stock'));


        $vacancy_rate = array_count_values(array_column($data,'stock'));
        $vacancy_rate = array_key_exists('0',$vacancy_rate) ? $vacancy_rate['0'] : 0;
        $vacancy_rate =  $total_config_counts==0 ? 0 : number_format($vacancy_rate / $total_config_counts,2) * 100;

        $use_rate =  100 - $vacancy_rate;
        $vacancy_rate =  $total_config_counts==0 ? '--' : $vacancy_rate . "%";
        $use_rate = $total_config_counts==0 ? '--' : $use_rate . "%";


        $total_layup_nums = array_sum(array_column($data,'layup_num'));

        $datas=['title'=>$title,'data'=>$data,
            'total_config_counts'=>$total_config_counts,
            'usage_1_counts'=>$usage_1_counts,
            'usage_2_counts'=>$usage_2_counts,
            'usage_3_counts'=>$usage_3_counts,
            'total_counts'=>$total_counts,
            'vacancy_rate'=>$vacancy_rate,
            'use_rate'=>$use_rate,
            'total_layup_nums'=>$total_layup_nums
        ];
        return CatchResponse::success($datas,'');
    }
    //库存导出
    public function exportStock(Request $request, Excel $excel, stockExport $stockExport){

        return CatchResponse::success($excel->save($stockExport, 'export/stocks'));
//        return CatchResponse::success($this->stockModel->getExportList(), 'export/stocks');
    }
    /**
     * 库存状态
     * @time 2022/01/23 13:52
     * @param Request $request
     * @return Response
     */
    public function statusEdit(Request $request){
        $params = $request->post();
        if(empty($params['id']) || empty($params['status'])){
            return CatchResponse::success('缺少参数');
        }
        $info = Db::table('db_stock')->where('id',$params['id'])->find();
        $data=[];
        if($params['status']=='Good'){
            $data['Good_Qty'] = $info['number']-$info['out_number'];
            $data['NG_Qty'] = 0;
            $data['Hold_Qty'] = 0;
        }else if($params['status']=='NG'){
            $data['NG_Qty'] = $info['number']-$info['out_number'];
            $data['Good_Qty'] = 0;
            $data['Hold_Qty'] = 0;
        }else if($params['status']=='Hold'){
            $data['Hold_Qty'] = $info['number']-$info['out_number'];
            $data['Good_Qty'] = 0;
            $data['NG_Qty'] = 0;
        }
        Db::table('db_stock')->where('id',$params['id'])->update($data);
        Db::table('db_tray')->where('tray_id',$info['tray_id'])->update(['goods_status'=>$params['status']]);
        return CatchResponse::success('操作成功');
    }

    //批量修改状态
    public function batchStatusEdit(Request $request){
        $params = $request->post();
        if(empty($params['ids']) || empty($params['status'])){
            return CatchResponse::success('缺少参数');
        }

        Db::startTrans();
        try {

            foreach ($params['ids'] as $pk){
                $info = Db::table('db_stock')->where('id',$pk)->find();
                $data=[];
                if($params['status']=='Good'){
                    $data['Good_Qty'] =  array_sum([$info['Good_Qty'],$info['Hold_Qty'],$info['NG_Qty']]);
                    $data['NG_Qty'] = 0;
                    $data['Hold_Qty'] = 0;
                }else if($params['status']=='NG'){
                    $data['NG_Qty'] =  array_sum([$info['Good_Qty'],$info['Hold_Qty'],$info['NG_Qty']]);
                    $data['Good_Qty'] = 0;
                    $data['Hold_Qty'] = 0;
                }else if($params['status']=='Hold'){
                    $data['Hold_Qty'] =  array_sum([$info['Good_Qty'],$info['Hold_Qty'],$info['NG_Qty']]);
                    $data['Good_Qty'] = 0;
                    $data['NG_Qty'] = 0;
                }
                Db::table('db_stock')->where('id',$pk)->update($data);
                Db::table('db_tray')->where('tray_id',$info['tray_id'])->update(['goods_status'=>$params['status']]);
            }

            Db::commit();
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail('批量操作状态失败');
        }

        return CatchResponse::success('操作成功');
    }

    /**
     * 库存状态
     * @time 2022/01/23 13:52
     * @param Request $request
     * @return Response
     */
    public function inventory(Request $request){
        $config_name = $request->post('config_name');
        $tray_id=$request->post('tray_id');
        $config_id=Db::table('db_warehouse_config')->where('name',$config_name)->value('config_id');
        $where=[];
        if(!empty($config_id)){
            $where[]=['a.config_id','=',$config_id];
        }
        $where[]=['a.deleted_at','=',0];
        $where[]=['a.type','=',0];
        if(!empty($tray_id)){
            $where[]=['a.tray_id','=',$tray_id];
        }
        $income=Db::table('db_tray')
                ->alias('a')
                ->leftJoin('db_warehousing_product b','a.tray_id = b.tray_id and a.warehousing_son_id=b.warehousing_son_id')
                ->leftJoin('users c','a.creator_id=c.id')
                ->leftJoin('db_warehouse_config e','a.config_id=e.config_id')
                ->leftJoin('db_warehousing f','a.warehousing_id=f.warehousing_id')
                ->leftJoin('db_project g','f.project_client=g.project_id')
                ->leftJoin('db_warehousing_son h','a.warehousing_son_id=h.warehousing_son_id')
                ->field('
                a.id,
                a.warehousing_id,
                a.warehousing_son_id,
                a.tray_id,
                a.config_id,
                a.number,
                a.box_number,
                a.created_at,
                a.goods_status,
                a.creator_id,
                a.type,
                b.goods_id,
                b.goods_name,
                b.goods_Cname,
                b.packing_num,
                b.unit_name,
                c.username,
                e.name as config_name,
                f.customer_business_number,
                g.project_name,
                h.batch_number,
                a.updated_at
                ')
                ->where($where)
                ->select()
                ->toArray();
        foreach ($income as $k=>$v){
            $income[$k]['creator_id']=$v['username'];
            $income[$k]['created_at']=date('Y-m-d H:m:s',$v['created_at']);
            $income[$k]['updated_at']=!empty($v['updated_at'])?date('Y-m-d H:m:s',$v['updated_at']):$income[$k]['created_at'];
            if(empty($v['goods_name'])){
                $stock = Db::table('db_stock')->where('tray_id',$v['tray_id'])->find();
                $income[$k]['goods_id']=$stock['goods_id'];
                $income[$k]['goods_name']=$stock['goods_name'];
                $income[$k]['goods_Cname']=$stock['goods_Cname'];
                $income[$k]['packing_num']=$stock['packing_num'];
                $income[$k]['unit_name']=$stock['unit_name'];
            }
        }
        $where=[];
        if(!empty($config_id)){
            $where[]=['a.config_id','=',$config_id];
        }
        if(!empty($tray_id)){
            $where[]=['a.tray_id','=',$tray_id];
        }
        $where[]=['a.deleted_at','=',0];
        $where[]=['a.type','=',1];
        $out=Db::table('db_tray')
            ->alias('a')
            ->leftJoin('db_pick b','a.tray_id=b.tray_id and a.warehousing_son_id=b.warehouse_out_son_id')
            ->leftJoin('db_warehouse_out_son c','b.warehouse_out_son_id=c.warehouse_out_son_id')
            ->leftJoin('users d','a.creator_id=d.id')
            ->leftJoin('db_warehouse_config e','a.config_id=e.config_id')
            ->leftJoin('db_warehouse_out f','a.warehousing_son_id=f.warehouse_out_id')
            ->leftJoin('db_project g','f.project_client=g.project_id')
            ->field('
                a.id,
                a.warehousing_id,
                a.warehousing_son_id,
                a.tray_id,
                a.config_id,
                a.number,
                a.box_number,
                a.created_at,
                a.goods_status,
                a.creator_id,
                a.type,
                c.goods_id,
                c.goods_name,
                c.goods_Cname,
                c.packing_num,
                c.unit_name,
                d.username,
                e.name as config_name,
                f.customer_business_number,
                g.project_name,
                a.batch_number,
                a.updated_at
                ')
            ->where($where)
            ->select()
            ->toArray();
        foreach ($out as $k=>$v){
            $out[$k]['creator_id']=$v['username'];
            $out[$k]['created_at']=date('Y-m-d H:m:s',$v['created_at']);
            $out[$k]['updated_at']=!empty($v['updated_at'])?date('Y-m-d H:m:s',$v['updated_at']):$out[$k]['created_at'];
            if(empty($v['goods_name'])){
                $stock = Db::table('db_stock')->where('tray_id',$v['tray_id'])->find();
                $out[$k]['goods_id']=$stock['goods_id'];
                $out[$k]['goods_name']=$stock['goods_name'];
                $out[$k]['goods_Cname']=$stock['goods_Cname'];
                $out[$k]['packing_num']=$stock['packing_num'];
                $out[$k]['unit_name']=$stock['unit_name'];
            }
        }
        $list=$income;
        $trays=[];
        foreach ($out as $k=>$v){
            array_push($list,$v);
            array_push($trays,$v['tray_id']);
        }
        $sort=array_column($list,'id');
        array_multisort($sort,SORT_ASC,$list);
        $stock=[];
        foreach ($income as $k=>$v){
            if(!in_array($v['tray_id'],$trays)){
                array_push($stock,$v);
            }
        }
        $data=['stock'=>$stock,'list'=>$list];
        return CatchResponse::success($data,'');
    }
    /**
     * 修改托盘
     * @time 2022/01/23 13:52
     * @param Request $request
     * @return Response
     */
    public function upTray(Request $request){
        $params = $request->post();
        $stock = Db::table('db_stock')->where('stock_id',$params['stock_id'])->find();
        if(empty($stock)){
            return CatchResponse::fail('操作出错！');
        }
        try {
            Db::table('db_stock')->where('stock_id',$params['stock_id'])->update(['tray_id'=>$params['tray_id'],'updated_at'=>time()]);
            $where=[];
            $where[]=['warehousing_son_id','=',$stock['warehousing_son_id']];
            $where[]=['tray_id','=',$stock['tray_id']];
            Db::table('db_tray')->where($where)->update(['tray_id'=>$params['tray_id']]);
            Db::commit();
            return CatchResponse::success([],'操作成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return CatchResponse::fail('操作失败');
        }
    }

    //库存统计
    public function statistics(CatchAuth $auth,Request $request){
        $user = $auth->user();

        $this_month_days = date('t');

        $dayData = [];
        $stockData = [];

        for ($i=1;$i<=$this_month_days;$i++){
            $addI = $i - 1;
            if($i < date('j')){
//                $stockData[$i] = 0;
                $stockData[$i] = '';//没有数据的不展示了,不然图表0会展示不美观。
            }
            $dayData[$i] = strtotime("+$addI day" ,strtotime("first Day of this month 00:00:00"));
        }

        $statStockModel = new StatStock;

        if($user['type'] === 1){//管理员
            $statStock = $statStockModel->whereMonth('record_at')->select()->toArray();;
        }else{//商户
            $statStock = $statStockModel->where('tenant_id',$user['tenant_id'])->whereMonth('record_at')->select()->toArray();;
        }

        array_walk($statStock,function($value,$key) use ($dayData,&$stockData){
            $index = array_search($value['record_at'],$dayData);
//            $stockData[$index] += $value['stock_count'];
            $stockData[$index]  = (int)$stockData[$index] +  (int)$value['stock_count'];
        });

        return CatchResponse::success([
            'day'=> array_keys($dayData),//日期
            'stockData'=>array_values($stockData),//曲线图
            'totalStockNumber'=>(new StockModel)->getTotalStockNumber(),//库存数
            'rate'=>(new WarehouseConfig)->rate(),//库位使用率
            'warehousingNumber'=>(new Warehousing)->todayNumber(),//入库数量
            'warehouseOutNumber'=>(new WarehouseOut)->todayNumber(),//出库数量
            'distribution'=>(new StockModel)->distribution(),//分布
            'totalProjectNumber'=>(new Project)->getTotalProjectNumber(),//总项目数
            'totalProductNumber'=>(new Product)->getTotalProductNumber()//总商品数
        ],'success');
    }


}